In this exercise, I learnt how to create an interactive chart in R
packages = c('ggiraph', 'plotly', 'DT', 'patchwork',
'gganimate', 'tidyverse', 'readxl', 'gifski',
'gapminder')
for (p in packages){
if(!require(p, character.only = T)){
install.packages(p)
}
library(p, character.only = T)
}
exam_data <- read_csv("data/Exam_data.csv")
Firstly, plot a normal dot plot using ggplot2 with the Maths results:
ggplot(data=exam_data,
aes(x = MATHS)) +
geom_dotplot(binwidth=2.5,
dotsize = 0.5) +
scale_y_continuous(NULL,
breaks = NULL)
Convert to ggiraph interactive dot plot, with aesthetic mapping for the tooltip.
The girafe function passes the plot and converts it into an svg with specified width and height.
p <- ggplot(data=exam_data,
aes(x = MATHS)) +
geom_dotplot_interactive(
aes(tooltip = ID),
stackgroups = TRUE,
binwidth = 1,
method = "histodot") +
scale_y_continuous(NULL,
breaks = NULL)
girafe(
ggobj = p,
width_svg = 6,
height_svg = 6*0.618
)
p <- ggplot(data=exam_data,
aes(x = MATHS)) +
geom_dotplot_interactive(
aes(tooltip = CLASS, data_id=CLASS),
stackgroups = TRUE,
binwidth = 1,
method = "histodot") +
scale_y_continuous(NULL,
breaks = NULL)
girafe(
ggobj = p,
width_svg = 6,
height_svg = 6*0.618
)
We first have to create a new column to combine both the Student ID and Class. We do this by using the mutate function.
exam_data <- exam_data %>%
mutate(CLASSID = paste0(CLASS,", ", ID))
p <- ggplot(data=exam_data,
aes(x = MATHS)) +
geom_dotplot_interactive(
aes(tooltip = CLASSID, data_id=CLASS),
stackgroups = TRUE,
binwidth = 1,
method = "histodot") +
scale_y_continuous(NULL,
breaks = NULL)
girafe(
ggobj = p,
width_svg = 6,
height_svg = 6*0.618
)
p <- ggplot(data=exam_data,
aes(x = MATHS)) +
geom_dotplot_interactive(
aes(data_id = CLASS),
stackgroups = TRUE,
binwidth = 1,
method = "histodot") +
scale_y_continuous(NULL,
breaks = NULL)
girafe(
ggobj = p,
width_svg = 6,
height_svg = 6*0.618,
options = list(
opts_hover(css = "fill: #202020;"),
opts_hover_inv(css = "opacity:0.2;")
)
)
exam_data$onclick <- sprintf("window.open(\"%s%s\")",
"https://www.moe.gov.sg/schoolfinder?journey=Primary%20school", as.character(exam_data$ID) )
p <- ggplot(data=exam_data,
aes(x = MATHS)) +
geom_dotplot_interactive(
aes(onclick = onclick),
stackgroups = TRUE,
binwidth = 1,
method = "histodot") +
scale_y_continuous(NULL,
breaks = NULL)
girafe(
ggobj = p,
width_svg = 6,
height_svg = 6*0.618)
p1 <- ggplot(data=exam_data,
aes(x = MATHS)) +
geom_dotplot_interactive(
aes(tooltip = ID, data_id = ID),
stackgroups = TRUE,
binwidth = 1,
method = "histodot") +
coord_cartesian(xlim=c(0,100)) +
scale_y_continuous(NULL,
breaks = NULL)
p2 <- ggplot(data=exam_data,
aes(x = ENGLISH)) +
geom_dotplot_interactive(
aes(data_id = ID),
stackgroups = TRUE,
binwidth = 1,
method = "histodot") +
coord_cartesian(xlim=c(0,100)) +
scale_y_continuous(NULL,
breaks = NULL)
girafe(code = print(p1 / p2),
width_svg = 6,
height_svg = 6,
options = list(
opts_hover(css = "fill: #202020;"),
opts_hover_inv(css = "opacity:0.2;")
)
)
The following shows how to create an interactive chart using the package plotly.
We first plot a basic scatter plot:
plot_ly(data = exam_data,
x = ~ENGLISH,
y = ~MATHS)
We can see the interactive elements in the output, with the basic hovering showing the English and Math (E, M) scores.
plot_ly(data = exam_data,
x = ~ENGLISH,
y = ~MATHS,
color = ~RACE)
plot_ly(data = exam_data,
x = ~ENGLISH,
y = ~MATHS,
color = ~RACE,
colors = "Set1")
Define a colour palette using a vector and assigning it to the corresponding number of bins
pal <- c("red", "purple", "blue", "green")
plot_ly(data = exam_data,
x = ~ENGLISH,
y = ~MATHS,
color = ~RACE,
colors = pal)
Using text to add tool tips on hover.
plot_ly(data = exam_data,
x = ~ENGLISH,
y = ~MATHS,
text = ~paste("Student ID:", ID,
"<br>Class:", CLASS),
color = ~RACE,
colors = "Set1")
Using layout to add a Title and fix a range for the axes.
We pass the plot through the ggplotly function:
Using the highlight_key function of the plotly package to synchronise between the 2 plots on selection.
d <- highlight_key(exam_data)
p1 <- ggplot(data=d,
aes(x = MATHS,
y = ENGLISH)) +
geom_point(size=1) +
coord_cartesian(xlim=c(0,100),
ylim=c(0,100))
p2 <- ggplot(data=d,
aes(x = MATHS,
y = SCIENCE)) +
geom_point(size=1) +
coord_cartesian(xlim=c(0,100),
ylim=c(0,100))
subplot(ggplotly(p1),
ggplotly(p2))
We will now add a data table beside the plot using the DT package. We can preview the data table using the following code:
DT::datatable(exam_data)
We can then link it during the crosstalk package. Using the bscols function, we can place the plots side by side.
d <- highlight_key(exam_data)
p <- ggplot(d,
aes(ENGLISH,
MATHS)) +
geom_point(size=1) +
coord_cartesian(xlim=c(0,100),
ylim=c(0,100))
gg <- highlight(ggplotly(p),
"plotly_selected")
crosstalk::bscols(gg,
DT::datatable(d),
widths = 5)
Firstly we create a normal bubble plot
globalPop <- read_xls("data/GlobalPopulation.xls")
ggplot(globalPop, aes(x = Old, y = Young,
size = Population,
colour = Country)) +
geom_point(alpha = 0.7,
show.legend = FALSE) +
scale_colour_manual(values = country_colors) +
scale_size(range = c(2, 12)) +
labs(title = 'Year: {frame_time}',
x = '% Aged',
y = '% Young')
Using the transition_time function to animate it over time, with the linear animation over time.
The country_colors is from the gapminder package.
ggplot(globalPop, aes(x = Old, y = Young,
size = Population,
colour = Country)) +
geom_point(alpha = 0.7,
show.legend = FALSE) +
scale_colour_manual(values = country_colors) +
scale_size(range = c(2, 12)) +
labs(title = 'Year: {frame_time}',
x = '% Aged',
y = '% Young') +
transition_time(Year) +
ease_aes('linear')